<template>
  <el-dialog
    v-model="visible"
    :title="title"
    :width="width"
    :close-on-click-modal="false"
    @close="handleClose"
  >
    <el-form
      ref="formRef"
      :model="formData"
      :rules="rules"
      :label-width="labelWidth"
      :label-position="labelPosition"
    >
      <el-form-item
        v-for="field in fields"
        :key="field.prop"
        :prop="field.prop"
        :label="field.label"
        :required="field.required"
      >
        <!-- 输入框 -->
        <el-input
          v-if="field.type === 'input'"
          v-model="formData[field.prop]"
          :placeholder="field.placeholder || `请输入${field.label}`"
          :disabled="field.disabled"
          :clearable="field.clearable !== false"
        />
        
        <!-- 文本域 -->
        <el-input
          v-else-if="field.type === 'textarea'"
          v-model="formData[field.prop]"
          type="textarea"
          :rows="field.rows || 4"
          :placeholder="field.placeholder || `请输入${field.label}`"
          :disabled="field.disabled"
        />
        
        <!-- 数字输入框 -->
        <el-input-number
          v-else-if="field.type === 'number'"
          v-model="formData[field.prop]"
          :min="field.min"
          :max="field.max"
          :step="field.step || 1"
          :precision="field.precision"
          :disabled="field.disabled"
          style="width: 100%"
        />
        
        <!-- 选择器 -->
        <el-select
          v-else-if="field.type === 'select'"
          v-model="formData[field.prop]"
          :placeholder="field.placeholder || `请选择${field.label}`"
          :disabled="field.disabled"
          :clearable="field.clearable !== false"
          :multiple="field.multiple"
          style="width: 100%"
        >
          <el-option
            v-for="option in field.options"
            :key="option.value"
            :label="option.label"
            :value="option.value"
            :disabled="option.disabled"
          />
        </el-select>
        
        <!-- 单选框组 -->
        <el-radio-group
          v-else-if="field.type === 'radio'"
          v-model="formData[field.prop]"
          :disabled="field.disabled"
        >
          <el-radio
            v-for="option in field.options"
            :key="option.value"
            :label="option.value"
            :disabled="option.disabled"
          >
            {{ option.label }}
          </el-radio>
        </el-radio-group>
        
        <!-- 复选框组 -->
        <el-checkbox-group
          v-else-if="field.type === 'checkbox'"
          v-model="formData[field.prop]"
          :disabled="field.disabled"
        >
          <el-checkbox
            v-for="option in field.options"
            :key="option.value"
            :label="option.value"
            :disabled="option.disabled"
          >
            {{ option.label }}
          </el-checkbox>
        </el-checkbox-group>
        
        <!-- 开关 -->
        <el-switch
          v-else-if="field.type === 'switch'"
          v-model="formData[field.prop]"
          :disabled="field.disabled"
          :active-text="field.activeText"
          :inactive-text="field.inactiveText"
        />
        
        <!-- 日期选择器 -->
        <el-date-picker
          v-else-if="field.type === 'date'"
          v-model="formData[field.prop]"
          :type="field.dateType || 'date'"
          :placeholder="field.placeholder || `请选择${field.label}`"
          :disabled="field.disabled"
          :clearable="field.clearable !== false"
          style="width: 100%"
        />
        
        <!-- 时间选择器 -->
        <el-time-picker
          v-else-if="field.type === 'time'"
          v-model="formData[field.prop]"
          :placeholder="field.placeholder || `请选择${field.label}`"
          :disabled="field.disabled"
          :clearable="field.clearable !== false"
          style="width: 100%"
        />
        
        <!-- 文件上传 -->
        <el-upload
          v-else-if="field.type === 'upload'"
          :action="field.action || '#'"
          :disabled="field.disabled"
          :multiple="field.multiple"
          :accept="field.accept"
          :before-upload="field.beforeUpload"
          :on-success="(response: any) => handleUploadSuccess(response, field.prop)"
        >
          <el-button type="primary">
            <el-icon><Upload /></el-icon>
            {{ field.uploadText || '点击上传' }}
          </el-button>
        </el-upload>
        
        <!-- 自定义插槽 -->
        <slot
          v-else-if="field.type === 'slot'"
          :name="field.slot"
          :field="field"
          :value="formData[field.prop]"
          :form-data="formData"
        />
      </el-form-item>
    </el-form>
    
    <template #footer>
      <el-button @click="handleClose">取消</el-button>
      <el-button type="primary" :loading="loading" @click="handleSubmit">
        {{ loading ? '提交中...' : '确定' }}
      </el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, watch, nextTick } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'

export interface FormField {
  prop: string
  label: string
  type: 'input' | 'textarea' | 'number' | 'select' | 'radio' | 'checkbox' | 'switch' | 'date' | 'time' | 'upload' | 'slot'
  required?: boolean
  disabled?: boolean
  placeholder?: string
  clearable?: boolean
  
  // 数字输入框
  min?: number
  max?: number
  step?: number
  precision?: number
  
  // 文本域
  rows?: number
  
  // 选择器/单选框/复选框
  options?: Array<{ label: string; value: any; disabled?: boolean }>
  multiple?: boolean
  
  // 开关
  activeText?: string
  inactiveText?: string
  
  // 日期选择器
  dateType?: 'date' | 'datetime' | 'daterange' | 'datetimerange'
  
  // 文件上传
  action?: string
  accept?: string
  uploadText?: string
  beforeUpload?: (file: File) => boolean
  
  // 自定义插槽
  slot?: string
  
  [key: string]: any
}

interface Props {
  modelValue: boolean
  title: string
  fields: FormField[]
  data?: Record<string, any>
  rules?: FormRules
  loading?: boolean
  width?: string
  labelWidth?: string
  labelPosition?: 'left' | 'right' | 'top'
}

const props = withDefaults(defineProps<Props>(), {
  data: () => ({}),
  rules: () => ({}),
  loading: false,
  width: '600px',
  labelWidth: '100px',
  labelPosition: 'right'
})

const emit = defineEmits<{
  'update:modelValue': [value: boolean]
  submit: [data: Record<string, any>]
  close: []
}>()

const formRef = ref<FormInstance>()
const visible = ref(false)
const formData = ref<Record<string, any>>({})

// 监听显示状态
watch(() => props.modelValue, (val) => {
  visible.value = val
  if (val) {
    initFormData()
  }
})

watch(visible, (val) => {
  emit('update:modelValue', val)
})

// 初始化表单数据
const initFormData = () => {
  const data: Record<string, any> = {}
  
  props.fields.forEach(field => {
    if (props.data[field.prop] !== undefined) {
      data[field.prop] = props.data[field.prop]
    } else {
      // 设置默认值
      switch (field.type) {
        case 'checkbox':
          data[field.prop] = []
          break
        case 'switch':
          data[field.prop] = false
          break
        case 'number':
          data[field.prop] = field.min || 0
          break
        default:
          data[field.prop] = ''
      }
    }
  })
  
  formData.value = data
}

// 处理提交
const handleSubmit = async () => {
  if (!formRef.value) return
  
  try {
    const valid = await formRef.value.validate()
    if (valid) {
      emit('submit', { ...formData.value })
    }
  } catch (error) {
    console.error('表单验证失败:', error)
  }
}

// 处理关闭
const handleClose = () => {
  visible.value = false
  nextTick(() => {
    formRef.value?.resetFields()
  })
  emit('close')
}

// 处理文件上传成功
const handleUploadSuccess = (response: any, prop: string) => {
  formData.value[prop] = response.url || response.data?.url
}
</script>

<style lang="scss" scoped>
:deep(.el-form-item__label) {
  font-weight: 500;
}

:deep(.el-upload) {
  width: 100%;
}
</style>
